package com.nercel.dsj.gksales.api.controller;

import com.nercel.dsj.gksales.exception.ResponseCode;
import com.nercel.dsj.gksales.exception.RestApiException;
import com.nercel.dsj.gksales.model.ListResult;
import com.nercel.dsj.gksales.model.QueryParams;
import com.nercel.dsj.gksales.model.ResponseResult;
import com.nercel.dsj.gksales.model.dto.ImportResultDTO;
import com.nercel.dsj.gksales.model.dto.UserInfoResultDTO;
import com.nercel.dsj.gksales.model.dto.UserParamsDTO;
import com.nercel.dsj.gksales.model.dto.UserUpdatePasswordParamsDTO;
import com.nercel.dsj.gksales.model.entity.User;
import com.nercel.dsj.gksales.service.SalesChannelService;
import com.nercel.dsj.gksales.service.SmsService;
import com.nercel.dsj.gksales.service.UserService;
import com.nercel.dsj.gksales.util.ApiResultUtil;
import com.nercel.dsj.gksales.util.DateUtil;
import com.nercel.dsj.gksales.util.Md5Util;
import com.nercel.dsj.gksales.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Api(tags = "用户接口")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UserApiController extends BaseApiController {

    private final UserService userService;

    private final SmsService smsService;

    private final SalesChannelService salesChannelService;

    @Value("${app.upload.path}")
    protected String uploadPath;


    @GetMapping(value = "/api/v1/users")
    @ApiOperation(value = "用户查询")
    @ResponseBody
    public ListResult<User> query(
        @ApiParam(hidden = true) QueryParams queryParams,
        @ApiParam(value = "页码") @RequestParam(required = false) Integer page,
        @ApiParam(value = "单页数量") @RequestParam(required = false) Integer pageSize,
        @ApiParam(value = "电话") @RequestParam(required = false) String phone,
        @ApiParam(value = "用户名") @RequestParam(required = false) String name,
        @ApiParam(value = "员工编号") @RequestParam(required = false) String userNumber,
        @ApiParam(value = "渠道编号") @RequestParam(required = false) String channelNumber,
        @ApiParam(value = "渠道名称") @RequestParam(required = false) String channelName,
        @ApiParam(value = "关键词") @RequestParam(required = false) String keyword,
        @ApiParam(value = "用户来源") @RequestParam(required = false) Integer createByUserId,
        @ApiParam(value = "级别 0最高 1省  2市 3销售") @RequestParam(required = false) Integer level,
        @ApiParam(value = "省份ID") @RequestParam(required = false) Integer provinceId,
        @ApiParam(value = "城市ID") @RequestParam(required = false) Integer cityId,
        @ApiParam(value = "区域ID") @RequestParam(required = false) Integer regionId,
        @ApiParam(value = "级别管理员") @RequestParam(required = false) Boolean levelAdmin,
        @ApiParam(value = "激活的") @RequestParam(required = false, defaultValue = "1") Boolean activated
    ) {
        queryParams.put("keyword", keyword);
        queryParams.put("phone", phone);
        queryParams.put("name", name);
        queryParams.put("userNumber", userNumber);
        queryParams.put("channelNumber", channelNumber);
        queryParams.put("channelName", channelName);
        queryParams.put("createByUserId", createByUserId);
        queryParams.put("level", level);
        queryParams.put("levelAdmin", levelAdmin);
        queryParams.put("provinceId", provinceId);
        queryParams.put("cityId", cityId);
        queryParams.put("regionId", regionId);
        queryParams.put("activated", activated);
        return userService.listWithPaging(queryParams);
    }

    @PutMapping(value = "/api/v1/users/{id}")
    @ApiOperation(value = "更新用户信息")
    public User update(
        @ApiParam(value = "数据ID") @PathVariable Integer id,
        @ApiParam(value = "用户信息") @RequestBody User user
    ) {
        user.setId(id);
        user.setPassword(null);
        user.setSalt(null);
        user.setPhone(null);
        userService.update(user);
        return userService.findById(id);
    }

    @PutMapping(value = "/api/v1/users/{id}/password")
    @ApiOperation(value = "修改密码")
    public ResponseResult updatePassword(
        @ApiParam(value = "用户ID") @PathVariable Integer id,
        @RequestBody UserUpdatePasswordParamsDTO params
    ) {
        User user = userService.findById(id);
        if(user == null
                || !user.getPassword().equals(Md5Util.getMD5String(user.getSalt() + params.getPassword()))) {
            throw new RestApiException(ResponseCode.INVALID_PASSWORD);
        }
        String password = Md5Util.getMD5String(user.getSalt() + params.getNewPassword());
        user.setPassword(password);
        userService.update(user);
        return ApiResultUtil.success();
    }

    @PostMapping(value = "/api/v1/users/{id}/password")
    @ApiOperation(value = "重设密码", notes = "强制设置用户新密码，参数中只用传newPassword")
    public ResponseResult resetPassword(@ApiParam(value = "用户ID") @PathVariable Integer id,
                                         @RequestBody UserUpdatePasswordParamsDTO params
    ) {
        User user = userService.findById(id);
        String password = Md5Util.getMD5String(user.getSalt() + params.getNewPassword());
        user.setPassword(password);
        userService.update(user);
        return ApiResultUtil.success();
    }

    @PostMapping(value = "/api/v1/users/new-password")
    @ApiOperation(value = "通过短信验证码重设密码")
    public ResponseResult resetPasswordByVCode(
            @RequestBody UserUpdatePasswordParamsDTO params
    ) {
        User user = userService.findByPhone(params.getPhone());
        if(user == null){
            throw new RestApiException(ResponseCode.NOT_FOUND);
        }
        smsService.checkSmsVCode(params.getPhone(), params.getVcode());
        String password = Md5Util.getMD5String(user.getSalt() + params.getNewPassword());
        user.setPassword(password);
        userService.update(user);
        return ApiResultUtil.success();
    }

    @GetMapping(value = "/api/v1/users/{id}")
    @ApiOperation(value = "用户信息", response = User.class)
    public Object get(@ApiParam(value = "ID") @PathVariable Integer id) {
        User user = userService.findById(id);
        return ApiResultUtil.notNull(user);
    }

    @PostMapping(value = "/api/v1/users")
    @ApiOperation(value = "新增用户")
    public User create(@ApiParam(value = "用户信息") @RequestBody UserParamsDTO user) {
        if(StringUtils.isNotEmpty(user.getPhone()) && userService.findByPhone(user.getPhone()) != null){
            throw new RestApiException(ResponseCode.DUPLICATE_PHONE);
        }
        String salt = StringUtil.randomUUID().substring(0, 6);
        String pwd = StringUtil.randomUUID().substring(0, 6);
        String password = Md5Util.getMD5String(salt + pwd);
        user.setPassword(password);
        user.setSalt(salt);
        userService.save(user);
        Map<String, String> data = new HashMap<>();
        data.put(user.getPhone(), pwd);
        smsService.sendNewUserPwd(data);
        return userService.findById(user.getId());
    }

    @DeleteMapping(value = "/api/v1/users/{id}")
    @ApiOperation(value = "删除用户")
    public Object delete(@ApiParam(value = "用户ID") @PathVariable Integer id) {
        userService.delete(id);
        return ApiResultUtil.success();
    }

    @PutMapping(value = "/api/v1/users/{userId}/roles")
    @ApiOperation(value = "更新用户角色")
    public Object updateRoles(@ApiParam(value = "数据ID") @PathVariable Integer userId,
                            @ApiParam(value = "角色ID数组") @RequestBody List<Integer> ids) {
        userService.updateRoles(userId, ids);
        return ApiResultUtil.success();
    }

    @GetMapping(value = "/api/v1/users/exist/status")
    @ApiOperation(value = "用户存在状态", response = User.class)
    public Object checkUserExistStatus(
            @ApiParam(value = "电话") @RequestParam(required = false) String phone,
            @ApiParam(value = "用户名") @RequestParam(required = false) String username
    ) {
        if(phone != null && !phone.equals("") && userService.findByPhone(phone) != null){
            return ApiResultUtil.success("phone existed", true);
        }
        return ApiResultUtil.success("not existed", false);
    }

    @ApiOperation(value = "客户经理批量导入")
    @RequestMapping(value="/api/v1/users/import", method= RequestMethod.POST)
    public ImportResultDTO upload2(@RequestParam MultipartFile file, @RequestParam(defaultValue = "level") String level) {
        return userService.importFromExcel(getUploadFile(file), getUserId(), level);
    }


    protected File getUploadFile(MultipartFile file){
        String fileName = org.springframework.util.StringUtils.cleanPath(file.getOriginalFilename());
        long size = file.getSize();
        String[] fs = fileName.split("\\.");
        String exName = fs.length == 1 ? "" : "." + fs[fs.length-1];
        String newFilename = System.currentTimeMillis() + exName;
        String filePath = "/upload-files" + "/" + DateUtil.getDays() + "/";
        (new File(uploadPath + filePath)).mkdirs();
        String fullFilePath = uploadPath + filePath + newFilename;
        try {
            file.transferTo(new File(fullFilePath));
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return new File(fullFilePath);
    }


}
